package com.josework.springhelloworld.entity;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.*;
import java.util.Comparator;
import java.util.concurrent.Callable;
import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.function.Supplier;

@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class Apple {

    private String color;

    private Integer weight;

//    private List<Apple> inventory;

    public static List<Apple> filterApples(List<Apple> inventory, ApplePredicate p){
        List<Apple> result = new ArrayList<>();
        for (Apple apple : inventory) {
            if (p.test(apple)){
                result.add(apple);
            }
        }
        return result;
    }

    public static boolean isGreenApple(Apple apple){
        if (apple!= null && apple.getColor()!=null){
            return "green".equals(apple.getColor());
        }else {
            return false;
        }
    }

    public static boolean isHeavyApple(Apple apple){
        return apple.getWeight()>150;
    }


    public static List<Apple> filterGreenApple(List<Apple> inventory){
        List<Apple> result = new ArrayList<>();
        for (Apple apple : inventory) {
            if ("green".equals(apple.getColor())){
                result.add(apple);
            }
        }
        return result;
    }

    public static List<Apple> filterHeavyApple(List<Apple> inventory){
        List<Apple> result = new ArrayList<>();
        for (Apple apple : inventory) {
            if (apple.getWeight() >150){
                result.add(apple);
            }
        }
        return result;
    }

    public static void prettyPrintApple(List<Apple> inventory, ApplePrint p){
        for(Apple apple: inventory) {
            String output = p.accept(apple);
            System.out.println(output);
        }
    }

    public static <T> List<T> filter(List<T> list, Predicate<T> p){
        List<T> result = new ArrayList<>();
        for (T e: list){
            if (p.test(e)){
                result.add(e);
            }
        }
        return result;
    }

    public static void main(String[] args) {
        List<Apple> apples = Arrays.asList(new Apple("green", 148),
        new Apple("red", 152)
        ,new Apple("red", 155)
        ,new Apple("red", 146)
        ,new Apple("green", 155));
//        apples.sort(Comparator.comparingInt(Apple::getWeight));
        prettyPrintApple(apples,new AppleWeightPrint2());
        List<Apple> filter = filter(apples, (Apple apple) -> "red".equals(apple.getColor()));

        List<Integer> nums = Arrays.asList(2,45,6,7,88,23,56);
        List<Integer> filter1 = filter(nums, e -> e%2 ==0);

        List<Apple> filterApples = filterApples(apples, new AppleRedAndHeavyPredicate());

        int portNum = 4300;
       Runnable a = ()->{
            System.out.println(portNum);
        };

       a.run();

        Function<String,Integer> stringToInteger = (String s) -> Integer.parseInt(s);
        Function<String,Integer> stringToInteger2 = Integer::parseInt;

        Supplier<Apple> c1 = Apple::new;
        Apple a1 = c1.get();

        BiFunction<String,Integer,Apple> c2 = Apple::new;
        Apple a2 = c2.apply("red",156);


//        apples.sort((Apple o1,Apple o2)-> o1.getWeight().compareTo(o2.getWeight()));

        apples.sort((Comparator.comparing(Apple::getWeight)));

        apples.sort(Comparator.comparing(Apple::getWeight).reversed());

        apples.sort(Comparator.comparing(Apple::getWeight)
                .reversed()
                .thenComparing(Apple::getColor)
        );

        Predicate<Apple> redApple = (e)->{return "red".equals(e.getColor());};

        Function<Integer,Integer> f = x -> x+1;
        Function<Integer, Integer> g = x -> x * 2;
        Function<Integer, Integer> h = f.compose(g);
        int result = h.apply(1);



































    }

}
